using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace pong1
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Audio : Microsoft.Xna.Framework.GameComponent
    {
        EventCollection eventCollection;    // Stores reference to pending events list
        String[] eventsForThisGameObjectArray;  // Stores a list of events that this object polls for
        SoundEffect soundEffect1;
        String strEventReceiver;
        Dictionary<String, String> soundsList;

        public Audio(Game game)
            : base(game)
        {
            eventCollection = (EventCollection)Game.Services.GetService(typeof(EventCollection));
            strEventReceiver = "audio";
            soundsList = new Dictionary<String,String>();
            soundsList.Add("paddle1", "boing_1");
            soundsList.Add("paddle2", "boing_2");
            soundsList.Add("wallhit", "blip");
            soundsList.Add("balloffscreen", "bloop_x");
            
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            eventCollection.RegisterForEvent("playsound", strEventReceiver);    // register for 'playsound' event
            String eventsForThisObject;
            eventsForThisObject = eventCollection.GetEventsForReceiver(strEventReceiver);
            eventsForThisGameObjectArray = eventsForThisObject.Split(',');

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if (!eventCollection.IsEmpty())
            {
                Event e;
                for (int j = 0; j < eventsForThisGameObjectArray.Length; j++)       // For each event this paddle is listening for, retrieve and process the event
                {
                    e = eventCollection.RetrieveEvent(eventsForThisGameObjectArray[j]); 

                    if (e != null)
                    {
                        processEvent(e);
                    }
                }

            }
            
            base.Update(gameTime);
        }

        /// <summary>
        /// The event processor for all events handled by PongBall
        /// 
        /// </summary>
        /// <param name="e"></param>
        private void processEvent(Event e)
        {

            switch (e.EventName)
            {
                case "playsound":
                    try 
	                {
                        soundEffect1 = Game.Content.Load<SoundEffect>(soundsList[e.EventArguments[0].ArgumentValue]);
	                }
	                catch (Exception)
	                {
		                // Sound could not be loaded for some reason. Not a crisis log error and return.
                        return;
	                }
                    switch (e.EventArguments[0].ArgumentValue)
	                {
                       case "paddle1":
                            soundEffect1.Play(0.5f, 0.0f, 0.0f);
                            break;
                       case "paddle2":
                            soundEffect1.Play(0.5f, 0.0f, 0.0f);
                            break;
                       case "wallhit":  // No sound played on 'wallhit' because it's too noisy
                            //soundEffect1.Play(0.5f, 0.0f, 0.0f);
                            break;
                       case "balloffscreen":
                            soundEffect1.Play(0.5f, 0.0f, 0.0f);
                            break;
                       default:
                            break;
	                }
                    
                    break;
                default:
                    break;
            }
        }


    }
}
